

#pragma comment(lib, "ole32.lib")

#include "NetworkListManager.hpp"

#include <Strsafe.h>



const ULONG NUM_NETWORKS = 50;
namespace Network 
{
	void NetworkListManager::GetNetworks(NetworkList& networkList)
	{
		HRESULT hr = CoInitialize( NULL );

		INetworkListManager *pNetworkListManager = NULL; 
		hr = CoCreateInstance(CLSID_NetworkListManager, NULL,
			CLSCTX_ALL, IID_INetworkListManager,
			(LPVOID *)&pNetworkListManager);

		IEnumNetworkConnections *ppEnum;
		hr = pNetworkListManager->GetNetworkConnections(&ppEnum);


		IEnumNetworks *ppEnumNetwork;
		pNetworkListManager->GetNetworks(NLM_ENUM_NETWORK_ALL, &ppEnumNetwork);

		if (SUCCEEDED(hr)) {

			ULONG pceltFetched = 0;
			INetwork *pNetworks[NUM_NETWORKS];
			hr = ppEnumNetwork->Next(NUM_NETWORKS, pNetworks, &pceltFetched);

			if (SUCCEEDED(hr)) {
				for (ULONG i = 0; i < pceltFetched; ++i)
				{
					Network_ network;
					GetNetwork(pNetworks[i], network);
					networkList.push_back(network);
					pNetworks[i]->Release();
				}
			}

			ppEnumNetwork->Release();
		}
		pNetworkListManager->Release();
	}

	void NetworkListManager::GetNetwork(INetwork *pNetwork, Network_& network)
	{
		CComBSTR szTemp;
		pNetwork->GetName(&network.name);



		NLM_NETWORK_CATEGORY pCategory;
		pNetwork->GetCategory(&pCategory);
		GetCategoryString(pCategory, network.category);


		GUID pgdGuidNetworkId;
		pNetwork->GetNetworkId(&pgdGuidNetworkId);
		GetSzGuid(pgdGuidNetworkId, network.networkId);


		NLM_DOMAIN_TYPE pNetworkType;
		pNetwork->GetDomainType(&pNetworkType);
		GetDomainTypeString(pNetworkType, network.domainType);




		pNetwork->GetDescription(&network.description);


		NLM_CONNECTIVITY pConnectivity;
		pNetwork->GetConnectivity(&pConnectivity);
		GetConnectivityString(pConnectivity, network.connectivity);



		DWORD pdwLowDateTimeCreated, pdwHighDateTimeCreated, pdwLowDateTimeConnected, pdwHighDateTimeConnected;
		pNetwork->GetTimeCreatedAndConnected(&pdwLowDateTimeCreated, &pdwHighDateTimeCreated,
			&pdwLowDateTimeConnected, &pdwHighDateTimeConnected);

		FILETIME time;
		time.dwHighDateTime = pdwHighDateTimeCreated;
		time.dwLowDateTime = pdwLowDateTimeCreated;

		SYSTEMTIME stime;
		FileTimeToSystemTime(&time, &stime);

		TCHAR lpszString[MAX_PATH];
		StringCchPrintf(lpszString, MAX_PATH, TEXT("%02d/%02d/%d  %02d:%02d"),
			stime.wMonth, stime.wDay, stime.wYear,
			stime.wHour, stime.wMinute);

		network.timeCreated = lpszString;


		time.dwHighDateTime = pdwHighDateTimeConnected;
		time.dwLowDateTime = pdwLowDateTimeConnected;

		FileTimeToSystemTime(&time, &stime);

		StringCchPrintf(lpszString, MAX_PATH, TEXT("%02d/%02d/%d  %02d:%02d"),
			stime.wMonth, stime.wDay, stime.wYear,
			stime.wHour, stime.wMinute);

		network.timeConnected = lpszString;

	}

	void NetworkListManager::GetCategoryString(NLM_NETWORK_CATEGORY pCategory, CComBSTR& str)
	{
		switch(pCategory)
		{
		case NLM_NETWORK_CATEGORY_PUBLIC:
			str = L"Private Network";
			break;
		case NLM_NETWORK_CATEGORY_PRIVATE:
			str = L"Public Network";
			break;
		case NLM_NETWORK_CATEGORY_DOMAIN_AUTHENTICATED:
			str = L"Authenticated Network";
			break;
		}
	}

	void NetworkListManager::GetConnectivityString(NLM_CONNECTIVITY pConnectivity, CComBSTR& str)
	{
		switch(pConnectivity)
		{
		case NLM_CONNECTIVITY_DISCONNECTED:
			str = L"NLM_CONNECTIVITY_DISCONNECTED";
			break;
		case NLM_CONNECTIVITY_IPV4_NOTRAFFIC:
			str = L"NLM_CONNECTIVITY_IPV4_NOTRAFFIC";
			break;
		case NLM_CONNECTIVITY_IPV6_NOTRAFFIC:
			str = L"NLM_CONNECTIVITY_IPV6_NOTRAFFIC";
			break;

		case NLM_CONNECTIVITY_IPV4_SUBNET:
			str =  L"NLM_CONNECTIVITY_IPV4_SUBNET";
			break;

		case NLM_CONNECTIVITY_IPV4_LOCALNETWORK:
			str =  L"NLM_CONNECTIVITY_IPV4_LOCALNETWORK";
			break;
		case NLM_CONNECTIVITY_IPV4_INTERNET:
			str =  L"NLM_CONNECTIVITY_IPV4_INTERNET";
			break;
		case NLM_CONNECTIVITY_IPV6_SUBNET:
			str =  L"NLM_CONNECTIVITY_IPV6_SUBNET";
			break;
		case NLM_CONNECTIVITY_IPV6_LOCALNETWORK:
			str =  L"NLM_CONNECTIVITY_IPV6_LOCALNETWORK";
			break;
		case NLM_CONNECTIVITY_IPV6_INTERNET:
			str =  L"NLM_CONNECTIVITY_IPV6_INTERNET";
			break;
		}

		if (pConnectivity == NLM_CONNECTIVITY_DISCONNECTED)
		{
			str =  L"network disconnected";
		}

		if (pConnectivity & NLM_CONNECTIVITY_IPV4_NOTRAFFIC)
		{
			str =  L"network no traffic";
		}

		if (pConnectivity & NLM_CONNECTIVITY_IPV4_LOCALNETWORK)
		{
			str =  L"IPv4 local connectivity";
		}

		if (pConnectivity & NLM_CONNECTIVITY_IPV4_INTERNET)
		{
			str =  L"IPv4 internet connectivity";
		}

		if (pConnectivity & NLM_CONNECTIVITY_IPV6_LOCALNETWORK)
		{
			str =  L"IPv6 local connectivity";
		}

		if (pConnectivity & NLM_CONNECTIVITY_IPV6_INTERNET)
		{
			str =  L"IPv6 internet connectivity";
		}
	}

	void NetworkListManager::GetDomainTypeString(NLM_DOMAIN_TYPE pNetworkType, CComBSTR& str)
	{
		switch(pNetworkType)
		{
		case NLM_DOMAIN_TYPE_NON_DOMAIN_NETWORK:
			str =  L"Not Active Directory Network";
			break;
		case NLM_DOMAIN_TYPE_DOMAIN_NETWORK:
			str =  L"Active Directory Network";
			break;
		case NLM_DOMAIN_TYPE_DOMAIN_AUTHENTICATED:
			str =  L"Authenticated Active Directory Network";
			break;
		}
	}

	void NetworkListManager::GetSzGuid(GUID gdGuid, CComBSTR& str)
	{
		LPOLESTR szClsId;
		HRESULT hr = StringFromIID(gdGuid, &szClsId);
		if (FAILED(hr))
		{
			str =  L"{failed}";
		}
		CComBSTR bstrClsId = szClsId;
		CoTaskMemFree(szClsId);

		str =  bstrClsId;
	}

}